package com.mai4j.maiadmin.support.security.aop;


import com.mai4j.maiadmin.support.security.aop.annotation.*;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.security.access.AccessDeniedException;

import java.util.ArrayList;
import java.util.Collection;

/**
 * 微信公众号请关注: 开源螺丝钉
 * <br>
 * 码云请关注: <a href="https://gitee.com/xiyoufang">https://gitee.com/xiyoufang</a>
 * <br>
 * 哔哩哔哩请关注: <a href="https://space.bilibili.com/438927834">https://space.bilibili.com/438927834</a>
 *
 * @author xiyoufang
 */
public class AopAnnotationsAuthorizingMethodInterceptor implements MethodInterceptor {

    protected Collection<AuthorizingAnnotationMethodInterceptor> methodInterceptors;

    public AopAnnotationsAuthorizingMethodInterceptor() {
        methodInterceptors = new ArrayList<>();
        methodInterceptors.add(new AuthenticationAnnotationMethodInterceptor());
        methodInterceptors.add(new GuestAnnotationMethodInterceptor());
        methodInterceptors.add(new PermissionsAnnotationMethodInterceptor());
        methodInterceptors.add(new AccessPermissionAnnotationMethodInterceptor());
        methodInterceptors.add(new ModifyPermissionAnnotationMethodInterceptor());
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        assertAuthorized(invocation);
        return invocation.proceed();
    }

    protected void assertAuthorized(MethodInvocation methodInvocation) throws AccessDeniedException {
        Collection<AuthorizingAnnotationMethodInterceptor> authorizingAnnotationMethodInterceptors = getMethodInterceptors();
        if (authorizingAnnotationMethodInterceptors != null && !authorizingAnnotationMethodInterceptors.isEmpty()) {
            for (AuthorizingAnnotationMethodInterceptor authorizingAnnotationMethodInterceptor : authorizingAnnotationMethodInterceptors) {
                if (authorizingAnnotationMethodInterceptor.supports(methodInvocation)) {
                    authorizingAnnotationMethodInterceptor.assertAuthorized(methodInvocation);
                }
            }
        }
    }

    public Collection<AuthorizingAnnotationMethodInterceptor> getMethodInterceptors() {
        return methodInterceptors;
    }
}
